import os
import time
from datetime import datetime
import re

from base import create_movie_v3, chatveo
from base import oss_client
from service import service_audio
from service  import service_file
from service  import service_namespace
from utils import time_utils
from model.models import db, TSysNovelChapter, TSysFile, \
    TSysTokenUsageHistory, TSysVideo
from moviepy.editor import VideoFileClip

video_temp_folder_path = "../video_temp"
audio_temp_folder_path = "../audio_temp"
type_MP4="mp4"
type_PNG="png"



def create_video_from_chatveo(playboosks_json ,chapter_id, user_id):
    try:
        print('剧本获得完毕')
        if not os.path.exists(video_temp_folder_path):
            os.makedirs(video_temp_folder_path)

        output_video_file = str(chapter_id)+"-"+str(time.time()) + ".mp4"
        text_list = []

        videos_temp_chpater_path = video_temp_folder_path+os.sep +  str(chapter_id)+"-"+str(time.time())
        video_no=1

        fail_count=1
        #提交任务
        success_ids = []
        call_chatveo_endpoint_conut = 0
        for playbook_json in playboosks_json.get("value"):
            short_video_materials = []

            subtitles_json = playbook_json.get("subtitles")
            for subtitle in subtitles_json:
                text_list.append(subtitle)

            for video_promopt in playbook_json.get('video_promopts'):
                try:
                    success_id,result = chatveo.sync_task_submit_call(input_prompt=video_promopt.get('video_promopt'))
                    time.sleep(2)
                    if result == True:
                        success_ids.append(success_id)
                        call_chatveo_endpoint_conut +=1
                    else:
                        print('提交任务失败'+str(fail_count))
                        fail_count+=1

                except Exception as e:
                    print('提交短视频素材生成任务异常：' + str(e))
                    continue

        id_count = 0
        timestamp = time_utils.get_current_timestamp()
        chapter = TSysNovelChapter.query.filter_by(id=chapter_id).first()
        #获取结果
        for id in success_ids:
            try:
                get_result, cover_image_url, dest_temp_file_name = chatveo.get_task_result(task_id=id, file_path=videos_temp_chpater_path, temp_file_name=str(chapter_id) + '-' + str(video_no) + '.mp4')
                if get_result == False:
                    continue

                if id_count == 0:
                    result, cover_image_file_name,bucket_name = service_file.download_object_and_upload_to_oss(object_url=cover_image_url, chapter_id=chapter_id, user_id=user_id, type=service_namespace.IMAGES_BUCKET_NAME)
                    if chapter is not None and result:
                        tSysFile = TSysFile(
                            user_id=user_id,
                            correlation_id=chapter.novel_id,
                            correlation_type='novel',
                            correlation_sub_id=chapter_id,
                            name=chapter.title,
                            local_path=cover_image_file_name,
                            remote_path=bucket_name,
                            file_type=type_PNG,
                            create_date=datetime.now(),
                            update_date=datetime.now()
                        )
                        db.session.add(tSysFile)
                        db.session.commit()

                short_video_materials.append(dest_temp_file_name)


                if chapter is not None:
                    result,file_name,bucket_name = service_file.upload_file_to_oss(chapter_id=chapter_id, user_id=user_id,
                                                                                   file_path=dest_temp_file_name,
                                                                                   type=service_namespace.IMAGES_BUCKET_NAME)
                    if result:
                        tSysFile = TSysFile(
                            user_id=user_id,
                            correlation_id=chapter.novel_id,
                            correlation_type='novel',
                            correlation_sub_id=chapter_id,
                            name=chapter.title,
                            local_path=file_name,
                            remote_path=bucket_name,
                            file_type=type_MP4,
                            create_date=datetime.now(),
                            update_date=datetime.now()
                        )
                        db.session.add(tSysFile)
                        db.session.commit()

                        print("第" + str(video_no) + "段短视频生成完毕！")
                video_no += 1
            except Exception as e:
                print('获取短视频素材异常：' + str(e))
                continue

        if len(text_list) == 0:
            return {"success": False, "value": None, "msg": "视频创建异常，字幕创建异常"}

        subtiles = format_subtitle(txt_list=text_list)
        if len(subtiles) == 0:
            return {"success": False, "value": None, "msg": "视频创建异常，字幕创建异常"}

        dest_video_path = video_temp_folder_path+os.sep+output_video_file
        print('开始生成音频')
        create_audio_result = service_audio.create_short_audio_from_text(text_list=subtiles, chapter_id=chapter_id)

        if create_audio_result is None or create_audio_result == False:
            return {"success": False, "value": None, "msg": "视频创建异常，解说音频未创建成功"}

        mixed_audio_file_path = create_audio_result.get("value").get("mixed_audio_file_path")
        audio_temp_path = create_audio_result.get("value").get("audio_temp_path")
        handled_subtiles = create_audio_result.get("value").get("subtiles")

        #开始创建影片
        print('开始合成视频')
        create_movie_v3.create_video(all_short_video_materials=short_video_materials, subtiles_materials=handled_subtiles,
                                     audio_file=mixed_audio_file_path, output_file=dest_video_path)

        #存储入库
        chapter = TSysNovelChapter.query.filter_by(id=chapter_id).first()
        if chapter is not None:
            #上传视频
            oss_video_file_name=str(chapter_id)+"-"+str(time.time()) + ".mp4"
            bucket_name="video" + "-" + str(chapter.user_id) + "-" + str(chapter_id)
            oss_client.upload_file(file_path=dest_video_path, file_name=oss_video_file_name, bucket_name=bucket_name)
            tSysFile = TSysFile(
                user_id=chapter.user_id,
                correlation_id=chapter.novel_id,
                correlation_type='novel',
                correlation_sub_id=chapter_id,
                name=chapter.title,
                local_path=oss_video_file_name,
                remote_path=bucket_name,
                file_type=type_MP4,
                create_date=datetime.now(),
                update_date=datetime.now()
            )
            db.session.add(tSysFile)
            db.session.flush()
            file_id = tSysFile.id
            db.session.commit()
            return {"success": True, "value": {"file_id": file_id, "oss_video_file_name": oss_video_file_name,
                                               "video_file_path": dest_video_path,
                                               "mixed_audio_path": mixed_audio_file_path,
                                               "audio_temp_path": audio_temp_path,
                                               "cover_image_file_name": cover_image_file_name,
                                               "call_chatveo_endpoint_conut":call_chatveo_endpoint_conut,
                                               "videos_temp_chpater_path":videos_temp_chpater_path}, "msg": "视频创建完毕"}
    except Exception as e:
        print(e)
        return {"success": False, "value": None, "msg": "生成视频异常：" + str(e)}


#视频长度
def get_video_duration(file_path):
    if file_path is None:
        return 0

    vedio = VideoFileClip(file_path)
    if vedio is not None:
        vedio_duration = vedio.duration
        vedio.close()
        return vedio_duration
    else:
        return 0

def format_subtitle(txt_list):
    merged_string = ''.join(txt_list)
    merged_string = merged_string.replace("\n", "").replace("\r", "")
    subtitles_list = re.split(r'[。]', merged_string)
    subtitles_list.pop() #去掉最后的空字符
    return subtitles_list